package com.yunjian.common.utils;

import com.alibaba.fastjson.JSON;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.ConvertUtils;

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class BeanUtilsExtends extends BeanUtils {
	static {
		ConvertUtils.register(new DateConvert(), Date.class);
		ConvertUtils.register(new DateConvert(), java.sql.Date.class);
	}

	public static void copyProperties(Object dest, Object orig) {
		try {
			BeanUtils.copyProperties(dest, orig);
		} catch (IllegalAccessException ex) {
			System.err.println("dest：" + JSON.toJSONString(dest));
			System.err.println("orig：" + JSON.toJSONString(orig));
			ex.printStackTrace();
		} catch (InvocationTargetException ex) {
			System.err.println("dest：" + JSON.toJSONString(dest));
			System.err.println("orig：" + JSON.toJSONString(orig));
			ex.printStackTrace();
		}
	}

	public static void transMap2Bean2(Map<String, Object> map, Object obj) {
		if (map == null || obj == null) {
			return;
		}
		try {
			BeanUtils.populate(obj, map);
		} catch (Exception e) {
			System.out.println("transMap2Bean2 Error " + e);
		}
	}

	public static void transMap2Bean(Map<String, Object> map, Object obj) {

		try {
			BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass());
			PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();

			for (PropertyDescriptor property : propertyDescriptors) {
				String key = property.getName();

				if (map.containsKey(key)) {
					Object value = map.get(key);
					// 得到property对应的setter方法
					Method setter = property.getWriteMethod();
					setter.invoke(obj, value);
				}

			}

		} catch (Exception e) {
			System.out.println("transMap2Bean Error " + e);
		}
	}

	public static Map<String, Object> transBean2Map(Object obj) {

		if (obj == null) {
			return null;
		}
		Map<String, Object> map = new HashMap<>();
		try {
			BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass());
			PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
			for (PropertyDescriptor property : propertyDescriptors) {
				String key = property.getName();

				// 过滤class属性
				if (!key.equals("class")) {
					// 得到property对应的getter方法
					Method getter = property.getReadMethod();
					Object value = getter.invoke(obj);

					map.put(key, value);
				}

			}
		} catch (Exception e) {
			System.out.println("transBean2Map Error " + e);
		}

		return map;

	}

	public static Map<String, String> transBean2MapStr(Object obj) {

		if (obj == null) {
			return null;
		}
		Map<String, String> map = new HashMap<>();
		try {
			BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass());
			PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
			for (PropertyDescriptor property : propertyDescriptors) {
				String key = property.getName();

				// 过滤class属性
				if (!key.equals("class")) {
					// 得到property对应的getter方法
					Method getter = property.getReadMethod();
					Object value = getter.invoke(obj);
					if (null != value) {
						if (value instanceof Date) {
							value = DateUtils.getStrDate((Date) value);
						} if (value instanceof String) {
							value = (String)  value;
						} else {
							value = JSON.toJSONString(value);
						}
						map.put(key, value + "");
					}
				}

			}
		} catch (Exception e) {
			System.out.println("transBean2Map Error " + e);
		}

		return map;

	}

	public static void transMapStr2Bean(Map<String, String> map, Object obj) {

		try {
			BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass());
			PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();

			for (PropertyDescriptor property : propertyDescriptors) {
				String key = property.getName();

				if (map.containsKey(key)) {
					Object value = map.get(key);
					// 得到property对应的setter方法
					Method setter = property.getWriteMethod();
					if (value.equals("null")) {
						value = null;
					} else if (setter.getParameterTypes()[0].equals(Date.class)) {
						value = new DateConvert().convert(Date.class, value);
					} else if (setter.getParameterTypes()[0].equals(Integer.class)) {
						value = Integer.parseInt(value + "");
					} else if (setter.getParameterTypes()[0].equals(Long.class)) {
						value = Long.parseLong(value + "");
					} else if (setter.getParameterTypes()[0].equals(Double.class)) {
						value = Double.parseDouble(value + "");
					} else if (setter.getParameterTypes()[0].equals(Float.class)) {
						value = Float.parseFloat(value + "");
					} else if (setter.getParameterTypes()[0].equals(Boolean.class)) {
						value = Boolean.parseBoolean(value + "");
					} else if (setter.getParameterTypes()[0].equals(BigDecimal.class)) {
						value = new BigDecimal(value + "");
					} else if (setter.getParameterTypes()[0].equals(String.class)) {
						value = value + "";
					} else if (setter.getParameterTypes()[0].equals(List.class)) {
						value = JSON.parseArray(value + "", setter.getParameterTypes()[0]);
					} else {
						value = JSON.parseObject(value + "", setter.getParameterTypes()[0]);
					}
					setter.invoke(obj, value);
				}

			}

		} catch (Exception e) {
			System.out.println("transMap2Bean Error " + e);
		}
	}

	public static Map<String, String> transMapObj2MapStr(Map<String, Object> mapObj) {
		if(null == mapObj) {
			return null;
		}
        Map<String, String> mapStr = new HashMap<>();
		for(Map.Entry<String,Object> entry : mapObj.entrySet()) {
            mapStr.put(entry.getKey(),entry.getValue() + "");
        }
        return mapStr;
	}
}
